from flask import Flask, render_template, request, redirect, url_for, flash, session
from flask_login import LoginManager, login_user, logout_user, login_required, current_user
from werkzeug.security import generate_password_hash, check_password_hash
from datetime import datetime
import random
from models import db, User, Exam, Question, ExamRecord, WrongBook

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db.init_app(app)

login_manager = LoginManager(app)
login_manager.login_view = 'login'

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

@app.route('/')
def index():
    if current_user.is_authenticated:
        if current_user.role == 'teacher':
            return redirect(url_for('teacher_dashboard'))
        else:
            return redirect(url_for('student_dashboard'))
    return redirect(url_for('login'))

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        user = User.query.filter_by(username=username).first()
        if user and check_password_hash(user.password, password):
            login_user(user)
            flash('登录成功', 'success')
            if user.role == 'teacher':
                return redirect(url_for('teacher_dashboard'))
            else:
                return redirect(url_for('student_dashboard'))
        else:
            flash('用户名或密码错误', 'danger')
    return render_template('login.html')

@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        password2 = request.form['password2']
        if password != password2:
            flash('两次密码不一致', 'danger')
            return render_template('register.html')
        if User.query.filter_by(username=username).first():
            flash('用户名已存在', 'danger')
            return render_template('register.html')
        user = User(username=username, password=generate_password_hash(password), role='student')
        db.session.add(user)
        db.session.commit()
        flash('注册成功，请登录', 'success')
        return redirect(url_for('login'))
    return render_template('register.html')

@app.route('/logout')
@login_required
def logout():
    logout_user()
    flash('已退出登录', 'info')
    return redirect(url_for('login'))

@app.route('/teacher')
@login_required
def teacher_dashboard():
    if current_user.role != 'teacher':
        flash('无权限访问', 'danger')
        return redirect(url_for('index'))
    return render_template('teacher_dashboard.html')

@app.route('/student')
@login_required
def student_dashboard():
    if current_user.role != 'student':
        flash('无权限访问', 'danger')
        return redirect(url_for('index'))
    return render_template('student_dashboard.html')

@app.route('/create_exam', methods=['GET', 'POST'])
@login_required
def create_exam():
    if current_user.role != 'teacher':
        flash('无权限访问', 'danger')
        return redirect(url_for('index'))
    level_filter = request.form.get('level_filter') if request.method == 'POST' else None
    questions = Question.query
    if level_filter:
        questions = questions.filter_by(level=level_filter)
    questions = questions.all()
    if request.method == 'POST' and 'name' in request.form:
        name = request.form['name']
        start_time = request.form['start_time']
        end_time = request.form['end_time']
        question_ids = request.form.getlist('question_ids')
        if not name or not start_time or not end_time or not question_ids:
            flash('请填写完整信息并选择题目', 'danger')
            return render_template('create_exam.html', questions=questions, level_filter=level_filter)
        try:
            start_dt = datetime.strptime(start_time, '%Y-%m-%dT%H:%M')
            end_dt = datetime.strptime(end_time, '%Y-%m-%dT%H:%M')
        except Exception:
            flash('时间格式错误', 'danger')
            return render_template('create_exam.html', questions=questions, level_filter=level_filter)
        if end_dt <= start_dt:
            flash('结束时间必须晚于开始时间', 'danger')
            return render_template('create_exam.html', questions=questions, level_filter=level_filter)
        exam = Exam(name=name, start_time=start_dt, end_time=end_dt)
        db.session.add(exam)
        db.session.commit()
        for qid in question_ids:
            q = Question.query.get(int(qid))
            if q:
                q.exam_id = exam.id
        db.session.commit()
        flash('考试创建成功！', 'success')
        return redirect(url_for('teacher_dashboard'))
    return render_template('create_exam.html', questions=questions, level_filter=level_filter)

@app.route('/exams')
@login_required
def exams():
    if current_user.role != 'teacher':
        flash('无权限访问', 'danger')
        return redirect(url_for('index'))
    exams = Exam.query.order_by(Exam.start_time.desc()).all()
    return render_template('exams.html', exams=exams)

@app.route('/exam/<int:exam_id>')
@login_required
def exam_detail(exam_id):
    if current_user.role != 'teacher':
        flash('无权限访问', 'danger')
        return redirect(url_for('index'))
    exam = Exam.query.get_or_404(exam_id)
    # 成绩分布
    records = ExamRecord.query.filter_by(exam_id=exam_id).all()
    scores = [r.score for r in records]
    # 错词统计
    wrongs = db.session.query(WrongBook, Question).join(Question, WrongBook.question_id == Question.id).all()
    word_count = {}
    for w, q in wrongs:
        # 只统计本场考试的题目
        if q.exam_id == exam_id:
            if q.word not in word_count:
                word_count[q.word] = {'count': 0, 'meaning': q.meaning}
            word_count[q.word]['count'] += w.count
    wordcloud_data = [{'word': k, 'count': v['count'], 'meaning': v['meaning']} for k, v in word_count.items()]
    return render_template('exam_detail.html', exam=exam, scores=scores, wordcloud_data=wordcloud_data)
@app.route('/student_exams')
@login_required
def student_exams():
    if current_user.role != 'student':
        flash('无权限访问', 'danger')
        return redirect(url_for('index'))
    now = datetime.now()
    exams = Exam.query.filter(Exam.start_time <= now, Exam.end_time >= now).order_by(Exam.start_time.desc()).all()
    return render_template('student_exams.html', exams=exams)

@app.route('/do_exam/<int:exam_id>', methods=['GET', 'POST'])
@login_required
def do_exam(exam_id):
    if current_user.role != 'student':
        flash('无权限访问', 'danger')
        return redirect(url_for('index'))
    exam = Exam.query.get_or_404(exam_id)
    # 检查是否已参加过该考试
    record = ExamRecord.query.filter_by(user_id=current_user.id, exam_id=exam.id).first()
    if record:
        flash('你已参加过本场考试', 'info')
        return redirect(url_for('student_exams'))
    # 题目随机顺序
    if request.method == 'GET':
        questions = exam.questions[:]
        random.shuffle(questions)
        # 生成四选一选项（中英互测）
        quiz = []
        for q in questions:
            # 50%概率中英互换
            if random.random() < 0.5:
                # 英文->中文
                options = [q.meaning]
                wrongs = Question.query.filter(Question.id != q.id, Question.level == q.level).all()
                options += random.sample([w.meaning for w in wrongs], min(3, len(wrongs)))
                random.shuffle(options)
                quiz.append({'id': q.id, 'type': 'en2zh', 'stem': q.word, 'options': options, 'answer': q.meaning})
            else:
                # 中文->英文
                options = [q.word]
                wrongs = Question.query.filter(Question.id != q.id, Question.level == q.level).all()
                options += random.sample([w.word for w in wrongs], min(3, len(wrongs)))
                random.shuffle(options)
                quiz.append({'id': q.id, 'type': 'zh2en', 'stem': q.meaning, 'options': options, 'answer': q.word})
        session['quiz'] = quiz
        session['exam_id'] = exam.id
        return render_template('do_exam.html', exam=exam, quiz=quiz)
    # POST提交答卷
    quiz = session.get('quiz')
    if not quiz:
        flash('考试数据丢失，请重新进入考试', 'danger')
        return redirect(url_for('student_exams'))
    answers = {str(q['id']): q['answer'] for q in quiz}
    user_answers = {k: request.form.get(k) for k in answers.keys()}
    score = sum(1 for k in answers if user_answers.get(k) == answers[k])
    # 保存考试记录
    record = ExamRecord(user_id=current_user.id, exam_id=exam.id, score=score, submit_time=datetime.now(), details=str(user_answers))
    db.session.add(record)
    db.session.commit()
    # 错题统计
    for k in answers:
        if user_answers.get(k) != answers[k]:
            wrong = WrongBook.query.filter_by(user_id=current_user.id, question_id=int(k)).first()
            if wrong:
                wrong.count += 1
            else:
                db.session.add(WrongBook(user_id=current_user.id, question_id=int(k), count=1))
    db.session.commit()
    flash(f'考试提交成功，得分：{score} / {len(quiz)}', 'success')
    return render_template('exam_result.html', score=score, total=len(quiz), answers=answers, user_answers=user_answers, quiz=quiz)

@app.route('/student_records')
@login_required
def student_records():
    if current_user.role != 'student':
        flash('无权限访问', 'danger')
        return redirect(url_for('index'))
    records = ExamRecord.query.filter_by(user_id=current_user.id).order_by(ExamRecord.submit_time.desc()).all()
    for r in records:
        r.exam = Exam.query.get(r.exam_id)
    return render_template('student_records.html', records=records)

@app.route('/student_record/<int:record_id>')
@login_required
def student_record_detail(record_id):
    if current_user.role != 'student':
        flash('无权限访问', 'danger')
        return redirect(url_for('index'))
    record = ExamRecord.query.get_or_404(record_id)
    exam = Exam.query.get(record.exam_id)
    import ast
    user_answers = ast.literal_eval(record.details)
    quiz = []
    for q in exam.questions:
        answer = q.word if user_answers.get(str(q.id)) == q.word else q.meaning
        quiz.append({'id': q.id, 'stem': q.word, 'answer': answer})
    return render_template('exam_result.html', score=record.score, total=len(quiz), answers={}, user_answers=user_answers, quiz=quiz)

@app.route('/student_wrongbook')
@login_required
def student_wrongbook():
    if current_user.role != 'student':
        flash('无权限访问', 'danger')
        return redirect(url_for('index'))
    wrongs = db.session.query(WrongBook, Question).join(Question, WrongBook.question_id == Question.id).filter(WrongBook.user_id == current_user.id).all()
    wrong_list = []
    for w, q in wrongs:
        wrong_list.append({'word': q.word, 'meaning': q.meaning, 'count': w.count})
    return render_template('student_wrongbook.html', wrongs=wrong_list)

if __name__ == '__main__':
    app.run(debug=True)